package com.cloud.demo.redis;

import java.util.HashMap;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;


/**
 * ClassName: RedisDaoImpl <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON(可选). <br/>
 * date: 2016年3月16日 下午2:34:37 <br/>
 *
 * @author LiHao
 * @version 
 * @since JDK 1.6
 */
@Component("redisDao")
public class RedisDaoImpl extends BaseRedisDaoImpl<String, String> implements RedisDao {

	@Override
	public boolean existsKey(final String keyId) {
		Boolean flag = redisTemplate.execute(new RedisCallback<Boolean>() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] key = serializer.serialize(keyId);
				Boolean flag  = connection.exists(key);
				connection.close();
				return flag;
			}
		});
		return flag;
	}

	@Override
	public boolean set(final String key, final String value) {
		logger.info("保存key:{},value:{}",new Object[]{key,value});
		Boolean flag = redisTemplate.execute(new RedisCallback<Boolean>() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] keyByte = serializer.serialize(key);
				byte[] valByte = serializer.serialize(value);
				connection.set(keyByte, valByte);
				connection.close();
				return true;
			}
		});
		return flag;
	}
	@Override
	public boolean setExpire(final String key, final String value, final long seconds) {
		Boolean flag = redisTemplate.execute(new RedisCallback<Boolean>() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] keyByte = serializer.serialize(key);
				byte[] valByte = serializer.serialize(value);
//				connection.set(keyByte, valByte);
				connection.setEx(keyByte, seconds, valByte);
				connection.close();
				return true;
			}
		});
		return flag;
	}
	@Override
	public String get(final String key) {
		String value = redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] keyByte = serializer.serialize(key);
				byte[] valByte=connection.get(keyByte);
				if (valByte == null) {
					return null;
				}
				String value = serializer.deserialize(valByte);
				connection.close();
				return value;
			}
		});
		return value;
	}

	@Override
	public String getDel(final String key) {
		String value = redisTemplate.execute(new RedisCallback<String>() {
			public String doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] keyByte = serializer.serialize(key);
				byte[] valByte=connection.get(keyByte);
				if (valByte == null) {
					return null;
				}
				connection.del(keyByte);
				String value = serializer.deserialize(valByte);
				connection.close();
				return value;
			}
		});
		return value;
	}

	@Override
	public Long incr(final String key) {
		Long value = redisTemplate.execute(new RedisCallback<Long>() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] keyByte = serializer.serialize(key);
				Long value=connection.incr(keyByte);
				connection.close();
				return value;
			}
		});
		return value;
	}

	@Override
	public Long incrRes(final String key, final long chkNum,final String resVal) {
		Long value = redisTemplate.execute(new RedisCallback<Long>() {
			public Long doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] keyByte = serializer.serialize(key);
				Long value=connection.incr(keyByte);
				if(value>=chkNum){
//					byte[] valByte = serializer.serialize(resVal);
					connection.getSet(keyByte, serializer.serialize(resVal));
					//String getVal = serializer.deserialize(valByte);
				}
				connection.close();
				return value;
			}
		});
		return value;
	}

	@Override
	public boolean setMap(final String key, final Map<String, String> map) {
		logger.info("setMap保存key:{}",new Object[]{key});
		Boolean flag = redisTemplate.execute(new RedisCallback<Boolean>() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				Map<byte[], byte[]> byteMap=new HashMap<byte[], byte[]>(); 
				RedisSerializer<String> serializer = getRedisSerializer();
				for (Map.Entry<String, String> entry : map.entrySet()) {
					byte[] keyByte = serializer.serialize(entry.getKey());
					byte[] valByte = serializer.serialize(entry.getValue());
					byteMap.put(keyByte, valByte);
				}
				byte[] keyByte = serializer.serialize(key);
				connection.hMSet(keyByte, byteMap);
				connection.close();
				return true;
			}
		});
		return flag;
	}
	public boolean setMapExpire(final String key, final Map<String, String> map, final long seconds) {
		Boolean flag = redisTemplate.execute(new RedisCallback<Boolean>() {
			public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
				Map<byte[], byte[]> byteMap=new HashMap<byte[], byte[]>(); 
				RedisSerializer<String> serializer = getRedisSerializer();
				for (Map.Entry<String, String> entry : map.entrySet()) {
					byte[] keyByte = serializer.serialize(entry.getKey());
					byte[] valByte =null;
					if(entry.getValue()!=null){
						valByte = serializer.serialize(entry.getValue());
					}else{
						valByte = serializer.serialize("");
					}
					byteMap.put(keyByte, valByte);
				}
				byte[] keyByte = serializer.serialize(key);
				connection.hMSet(keyByte, byteMap);
				connection.expire(keyByte, seconds);
				connection.close();
				return true;
			}
		});
		return flag;
	}


	@Override
	public Map<String, String> getMap(final String key) {
		Map<String, String> map = redisTemplate.execute(new RedisCallback<Map<String,String>>() {
			public Map<String,String> doInRedis(RedisConnection connection) throws DataAccessException {
				RedisSerializer<String> serializer = getRedisSerializer();
				byte[] keyByte = serializer.serialize(key);
				Map<byte[], byte[]> byteMap = connection.hGetAll(keyByte);
				connection.close();
				
				Map<String, String> map = new HashMap<String, String>();
				for (Map.Entry<byte[], byte[]> entry : byteMap.entrySet()) {
					
					String keyStr = serializer.deserialize(entry.getKey());
					String valStr = serializer.deserialize(entry.getValue());
					map.put(keyStr,valStr);
					
				}
				return map;
			}
		});
		return map;
	}
	
}

